# COPYRIGHT BLABLA

# README:
# Turn left/right (A,D) each press will change speed

from ogrebase import OgreView, EventListener
import ogre.io.OIS as OIS
import ogre.renderer.OGRE as ogre
import ogre.gui.CEGUI as CEGUI
import time
import math
import os

if os.name == 'nt':
    CEGUI.System.setDefaultXMLParserName('ExpatParser')
else:
    CEGUI.System.setDefaultXMLParserName('TinyXMLParser')

def convertOISMouseButtonToCegui(buttonID):
    if buttonID == 0:
        return CEGUI.LeftButton
    elif buttonID == 1:
        return CEGUI.RightButton
    elif buttonID == 2:
        return CEGUI.MiddleButton
    elif buttonID == 3:
        return CEGUI.X1Button
    else:
        return CEGUI.LeftButton

def cegui_reldim(x):
    return CEGUI.UDim((x),0)

def cegui_vector2(x, y):
    return CEGUI.UVector2(cegui_reldim(x), cegui_reldim(y))

def cegui_color(x):
    return CEGUI.ColourRect(x,x,x,x)

def _PointHack(x, y):
    return CEGUI.Vector2(x, y)
CEGUI.Point = _PointHack

class CeGuiBase(OgreView, EventListener):
    def __init__(self, title="QuickGui...", fullscreen=False, \
            resolution=(1024, 768), resDir='media', \
            renderSystem=''):
        OgreView.__init__(self, title, fullscreen, resolution, resDir, renderSystem)
        EventListener.__init__(self,self.RenderWindow, True, True)
        self.set_window_resolution(resolution[0], resolution[1])
        self.CEGUIRenderer = 0
        self.CEGUISystem = 0
        self._init_cegui()
        self.ConfListItems = []

    def __del__(self):
        EventListener.__del__(self)
        del self.CEGUISystem
        del self.CEGUIRenderer


    def _init_render_window(self):
        OgreView._init_render_window(self)

    def _init_cegui(self):
        self.CEGUIRenderer = CEGUI.OgreCEGUIRenderer(self.RenderWindow,
                ogre.RenderQueueGroupID.RENDER_QUEUE_OVERLAY, False, 3000,
                self.SceneManager)
        self.CEGUISystem = CEGUI.System(self.CEGUIRenderer)
        CEGUI.Logger.getSingleton().loggingLevel = CEGUI.Insane

        CEGUI.SchemeManager.getSingleton().loadScheme("VanillaSkin.scheme")
        if not CEGUI.FontManager.getSingleton().isFontPresent("Commonwealth-10.font"):
            try:
                CEGUI.FontManager.getSingleton().createFont("Commonwealth-10.font")
            except:
                pass

        CEGUI.System.getSingleton().setDefaultMouseCursor("Vanilla-Images", "MouseArrow")
        CEGUI.System.getSingleton().setDefaultFont("Commonwealth-10")

        CEGUI.System.getSingleton().setGUISheet(
            CEGUI.WindowManager.getSingleton().loadWindowLayout("my.layout", False))

        wmgr = CEGUI.WindowManager.getSingleton()
        rt = CEGUI.System.getSingleton().getGUISheet()
        popupt = CEGUI.WindowManager.getSingleton().loadWindowLayout("Config.layout", False)
        CEGUI.WindowManager.getSingleton().loadWindowLayout("Error.layout", False)

        rt.addChildWindow(popupt)
        popupt.setPosition(cegui_vector2(.25,.25))
        self._subscribe_events()

    def _subscribe_events(self):
        wmgr = CEGUI.WindowManager.getSingleton()
        okButton = wmgr.getWindow('OKWindow/Ok')
        cancelButton = wmgr.getWindow('OKWindow').getChild(2)
        saveButton = wmgr.getWindow('ConfigWnd/SaveBtn')
        slider = wmgr.getWindow('ConfigWnd/Slider')
        self.SliderValue = wmgr.getWindow('ConfigWnd/SliderValueShow')
        okButton.subscribeEvent(CEGUI.PushButton.EventClicked, self, "_button_ok")
        cancelButton.subscribeEvent(CEGUI.PushButton.EventClicked, self, "_button_cancel")
        saveButton.subscribeEvent(CEGUI.PushButton.EventClicked, self, "_button_save")
        slider.subscribeEvent(CEGUI.Slider.EventValueChanged, self, "_slider_value")

    def _slider_value(self, args):
        value = args.window.getCurrentValue()
        self.SliderValue.setText("%.0f" % value)


    def _button_ok(self, args):
        wmgr = CEGUI.WindowManager.getSingleton()
        errorWin = wmgr.getWindow('OKWindow')
        self._add_list_element("Got Ok")
        rt = CEGUI.System.getSingleton().getGUISheet()
        rt.removeChildWindow(errorWin)

    def _button_cancel(self, args):
        wmgr = CEGUI.WindowManager.getSingleton()
        errorWin = wmgr.getWindow('OKWindow')
        valueString = wmgr.getWindow('ConfigWnd/TestValueEbx')
        valueString.setText('Got Cancel')
        self._add_list_element("Got Cancel")
        rt = CEGUI.System.getSingleton().getGUISheet()
        rt.removeChildWindow(errorWin)

    def _button_save(self, args):
        wmgr = CEGUI.WindowManager.getSingleton()
        errorWin = wmgr.getWindow('OKWindow')
        errorString = wmgr.getWindow('OKWindow/ErrorText')
        valueString = wmgr.getWindow('ConfigWnd/TestValueEbx')
        errorString.setText(valueString.getText())
        rt = CEGUI.System.getSingleton().getGUISheet()
        rt.addChildWindow(errorWin)
        errorWin.setPosition(cegui_vector2(.3,.3))

    def _add_list_element(self, text):
        wmgr = CEGUI.WindowManager.getSingleton()
        cnfLst = wmgr.getWindow('ConfigWnd/List')
        item = CEGUI.ListboxTextItem("%s: %s" %(time.ctime(), text))
        item.AutoDeleted = False
        item.setSelectionBrushImage("Vanilla-Images", "GenericBrush")
        if cnfLst.getItemCount() == 0:
            item.setSelected(True)
        else:
            item.setSelected(False)
        cnfLst.addItem(item)
        self.ConfListItems.append(item)
       

    def mouseMoved(self, evt):
        EventListener.mouseMoved(self, evt)
        CEGUI.System.getSingleton().injectMouseMove(evt.get_state().X.rel, evt.get_state().Y.rel)
        if evt.get_state().Z.rel != 0:
            #TODO
            pass
            #self.GuiManager.injectMouseWheelChange(evt.state.Z.rel)

        return True

    def mousePressed(self, evt, id):
        EventListener.mousePressed(self, evt, id)
        CEGUI.System.getSingleton().injectMouseButtonDown(\
                convertOISMouseButtonToCegui(id))
        return True

    def mouseReleased(self, evt, id):
        EventListener.mouseReleased(self, evt, id)
        CEGUI.System.getSingleton().injectMouseButtonUp(\
                convertOISMouseButtonToCegui(id))
        return True

    def keyPressed(self, evt):
        EventListener.keyPressed(self, evt)
        CEGUI.System.getSingleton().injectChar(evt.text)
        CEGUI.System.getSingleton().injectKeyDown(evt.key)
        return True

    def keyReleased(self, evt):
        EventListener.keyReleased(self, evt)
        CEGUI.System.getSingleton().injectKeyUp(evt.key)
        return True
        



class CeGuiView(object):
    def __init__(self):
        self.OgreView = CeGuiBase()
        self.QuitApplication = False

        self.OgreView.register_key_event(OIS.KC_ESCAPE, self._quit)
        self.OgreView.register_key_event(OIS.KC_A, self._left)
        self.OgreView.register_key_event(OIS.KC_D, self._right)
        self.Angle = 0
        self.Turn = 0.01

    def __del__(self):
        if self.OgreView is not None:
            self.deinit()

    def deinit(self):
        del self.OgreView
        self.OgreView = None

    def run(self):
        self._init_scene()
        self._init_base_gui()

        while not self.QuitApplication:
            self.OgreView.render()
            self.OgreView.update()
            self.set_cam_pos(self.Angle)
            time.sleep(0.01)
            self.Angle += self.Turn

    def _init_scene(self):
        self.OgreView.SceneManager.setAmbientLight(\
                ogre.ColourValue(0.7, 0.7, 0.7))
        self.OgreView.SceneManager.setSkyDome(True, 'Examples/CloudySky', 4,8)
        self.Light = self.OgreView.SceneManager.createLight('mainlight')
        self.Light.setPosition(ogre.Vector3(20, 80, 50))

        self.RootNode = self.OgreView.SceneManager.getRootSceneNode()

        self.Ogre = self.OgreView.SceneManager.createEntity('Ogre', \
                'ogrehead.mesh')
        self.NodeOgre = self.RootNode.createChildSceneNode('nodeOgre')
        self.NodeOgre.setPosition(ogre.Vector3(0,0,0))
        self.NodeOgre.attachObject(self.Ogre)

        self.set_cam_pos(self.Angle)

    def _init_base_gui(self):
        pass

    def set_cam_pos(self, angle):
        self.OgreView.Camera.setPosition(ogre.Vector3(math.cos(angle)*200,\
                -10, math.sin(angle)*200))
        self.OgreView.Camera.lookAt(ogre.Vector3(0, 0, 1))
       

    def _quit(self, pressed):
        if not pressed:
            self.QuitApplication = True

    def _left(self, pressed):
        if pressed:
            self.Turn += 0.01

    def _right(self, pressed):
        if pressed:
            self.Turn -= 0.01

if __name__ == '__main__':
    try:
        t = CeGuiView()
        t.run()
        t.deinit()
    except ogre.OgreException, e:
        print e

